<template>
  <div class="container">
    <van-nav-bar title="搜索中心" left-arrow @click-left="$router.back()" />
    <!-- 搜索框 -->
    <van-search
      v-model="keyword"
      placeholder="请输入搜索关键词"
      @search="onSearch"
    />
    <!-- 联想词 -->
    <van-cell-group class="suggest-box" v-if="keyword">
      <!-- span高亮联想关键词 -->
      <van-cell
        v-for="(suggest, index) in suggestList"
        :key="index"
        icon="search"
        @click="onSearch(suggest.replace(`<span>${keyword}</span>`, keyword))"
      >
        <!-- 注意上面的onSearch方法要传参，否则搜索的还是搜索框里的关键词 -->
        <!-- <p><span>j</span>ava</p></van-cell -->
        <p v-html="suggest">
          <!-- <span>{{ suggest }}</span> -->
        </p></van-cell
      >
    </van-cell-group>
    <!-- 搜索历史记录 -->
    <div class="history-box" v-else>
      <div class="head">
        <span>历史记录</span>
        <!-- 删除全部 -->
        <van-icon @click="delAllHistory" name="delete"></van-icon>
      </div>
      <van-cell-group>
        <van-cell v-for="(his, index) in historyList" :key="index" @click="onSearch(his)">
          <a class="word_btn">{{ his }}</a>
          <!-- 删除单个 -->
          <van-icon
            @click="delHistory(index)"
            class="close_btn"
            slot="right-icon"
            name="cross"
          />
        </van-cell>
      </van-cell-group>
    </div>
  </div>
</template>

<script>
import { suggestApi } from '../../api/search'
/**
 * 存储用户的关键词搜索行为
 * 1.设计数据结构 -> ['1024', '小米]
 * 2.存储key名
 */
const TT_HS = 'TT_HS'
// 造假数据
// localStorage.setItem(TT_HS, JSON.stringify(['1024', '小米', '华为']))
export default {
  name: 'search-index',
  data () {
    return {
      // 搜索关键字
      keyword: '',
      // 历史记录
      historyList: JSON.parse(localStorage.getItem(TT_HS)) || [],
      // 联想词数组
      suggestList: [],
      timer: null // 定时器ID
    }
  },
  methods: {
    // 搜索事件回调
    onSearch (val) {
      console.log(val, this.keyword)
      /**
       * *1.存储搜索关键词语(排重)
       * *2.跳转搜索结果页并携带当前搜索关键词
       */
      if (!val) return false
      const historySet = new Set(this.historyList)
      historySet.add(val)
      this.historyList = [...historySet]
      localStorage.setItem(TT_HS, JSON.stringify(this.historyList))
      this.$router.push(`/search/result?q=${val}`)
    },
    // 删除单个搜索记录
    delHistory (index) {
      // 内存删除(软删除)
      this.historyList.splice(index, 1)
      // 本地删除(硬删除)
      localStorage.setItem(TT_HS, JSON.stringify(this.historyList))
    },
    // 删除全部历史记录
    delAllHistory () {
      // 内存删除(软删除)
      this.historyList = []
      // 本地删除(硬删除)
      localStorage.setItem(TT_HS, JSON.stringify(this.historyList))
    }
  },
  watch: {
    keyword () {
      // 简单数据类型直接用函数形式就可以，复杂数据类型要写完整形式
      console.log('搜索关键词变化了:', this.keyword)
      /**
       * 用户实时输入 -> 会多次调用接口查找列项此列表(用户还没输入完就发送了请求) -> 1.浪费服务器资源 2.公司成本
       * 解决方案：函数防抖 -> 解决高频触发场景 -> 在规定时间内不重复执行任务
       * 实现函数防抖：
       * 1.定义一个存储定时器ID的变量
       * 2.在定时器规定时间内，如果有重复执行就取消
       */
      // 清除定时器异步任务
      this.timer && clearTimeout(this.timer)
      // 函数防抖：当用户停止输入后600ms后处理联想词；
      // 如果600ms内再次输入内容，会清除上一次的任务，重新计时
      // 缓存定时器=>this.timer
      // 防抖不保证首次正常执行，节流保证首次正常执行
      this.timer = setTimeout(async () => {
        // 当搜索词为空，直接返回
        if (!this.keyword) {
          // 清空联想词列表
          this.suggestList = []
          // console.log(123)
          return false
        }
        try {
          // 在响应拦截器中已经默认return了data，所以可以直接解构
          const { data } = await suggestApi(this.keyword)
          console.log(data)
          if (data.options[0] === null) return false
          // 联想词中要有搜索词高亮的效果，在渲染时使用v-html，所以在修改数组时，对数据进行处理
          this.suggestList = data.options.map(word => word.toLowerCase().replace(this.keyword, `<span>${this.keyword}</span>`))
          // 存在bug，如果输入的关键词没有联想词列表，即返回的联想词列表为空，那么word就无法调用toLowerCase()方法和replace()方法this.suggestList = data.options.map(word => word?.toLowerCase().replace(this.keyword, `<span>${this.keyword}</span>`))
          // ES10语法 在变量后加个?，增强代码健壮性,但是该项目中ESLint不认识这个语法，会报错，关闭ESLint就不会保存了
        } catch (error) {
          console.dir(error)
        }
      }, 600)
    }
  }
}
</script>

<style scoped lang='less'>
.suggest-box {
  /deep/ .van-cell {
    padding: 10px 20px;
    color: #999;
    p {
      span {
        color: red;
      }
    }
  }
}
.history-box {
  padding: 0 20px;
  .head {
    line-height: 36px;
    color: #999;
    text-align: left;
    .van-icon {
      font-size: 16px;
      float: right;
      margin-top: 10px;
    }
  }
  .van-cell {
    padding: 10px 0;
  }
  .word_btn {
    color: #3296fa;
  }
  .close_btn {
    margin-top: 5px;
    color: #999;
  }
}
</style>
